﻿using System;
using System.Collections.Generic;
using System.Linq;
using CP_SchoolForChildren_v0._1.Controllers.Support;

namespace CP_SchoolForChildren_v0._1.Controllers.Fuzzy
{
    class FuzzyModule
    {
        //public double FeeLow;
        //public double FeeAverage;
        //public double FeeHigh;

        public double HoiItPoint;
        public double ItPoint;
        public double TrungBinhPoint;
        public double HoiCaoPoint;
        public double CaoPoint;

        public double RateBinhThuong;
        public double RateCao;
        public double RateRatCao;


        public double UserFee; // Mức học phí mong muốn của người sử dụng
        public double feeMax;
        public double feeMin;

        public int GetFeeMax;
        public int GetFeeMin;
        public bool isHigh;



        public FuzzyModule(double userFee)
        {
            this.UserFee = userFee;
            //FeeLow = 0;
            //FeeAverage = 0;
            //FeeHigh = 0;
            GetFeeMax = 0;
            GetFeeMin = 0;
            isHigh = false;
        }

        public void GetInvestLevel(
            double FeeHoiIt,
            double FeeIt,
            double FeeTrungBinh,
            double FeeHoiCao,
            double FeeCao)
        {
            /* Trường hợp RÕ RÀNG */
            if (FeeHoiIt == 1)
            {
                feeMax = HoiItPoint;
                feeMin = 0;
                return;
            }
            if (FeeIt == 1)
            {
                feeMax = TrungBinhPoint;
                feeMin = HoiItPoint;
                return;
            }
            if (FeeTrungBinh == 1)
            {
                feeMax = HoiCaoPoint;
                feeMin = ItPoint;
                return;
            }
            if (FeeHoiCao == 1)
            {
                feeMax = CaoPoint;
                feeMin = TrungBinhPoint;
                return;
            }
            if (FeeCao == 1)
            {
                feeMax = CaoPoint;
                feeMin = CaoPoint;
                isHigh = true;
                return;
            }

            /* Trường hợp KHÔNG RÕ RÀNG */
            if (FeeHoiIt > 0 && FeeHoiIt < 1 && FeeIt > 0 && FeeIt < 1)
            {
                feeMax = HoiItPoint + (ItPoint - HoiItPoint) * FeeIt;
                feeMin = 0;
                return;
            }
            if (FeeTrungBinh > 0 && FeeTrungBinh < 1 && FeeIt > 0 && FeeIt < 1)
            {
                feeMax = ItPoint + (TrungBinhPoint - ItPoint) * FeeTrungBinh;
                feeMin = HoiItPoint;
                return;
            }
            if (FeeTrungBinh > 0 && FeeTrungBinh < 1 && FeeHoiCao > 0 && FeeHoiCao < 1)
            {
                feeMax = TrungBinhPoint + (HoiCaoPoint - TrungBinhPoint) * FeeHoiCao;
                feeMin = ItPoint;
                return;
            }
            if (FeeCao > 0 && FeeCao < 1 && FeeHoiCao > 0 && FeeHoiCao < 1)
            {
                if (UserFee <= CaoPoint)
                {
                    feeMax = HoiCaoPoint + (CaoPoint - HoiCaoPoint) * FeeHoiCao;
                    feeMin = TrungBinhPoint;
                    return;
                }
                else
                {
                    feeMin = CaoPoint;
                    feeMax = CaoPoint;
                    isHigh = true;
                }
                return;
            }

        }


        public void DoTheWork()
        {
            var fc = new FunctionController();
            var outlier = new OutliersDetected();

            // Lấy ra số học phí có trong DB
            // Sắp xếp học phí từ nhỏ đến lớn
            var tested = (fc.db.Schools.OrderBy(s => s.TuitionFee).Select(s => s.TuitionFee)).ToList();
            var distinctlist = (fc.db.Schools.OrderBy(s => s.TuitionFee).Select(s => s.TuitionFee)).Distinct().ToList();
            // Xác định và loại outliners cho học phí
            var listTuitionFeeInDb = outlier.Detection(tested, distinctlist);
            listTuitionFeeInDb = outlier.Detection(listTuitionFeeInDb);
            var tmp = new List<double>();
            var tmp2 = new List<double>();
            for (int i = 0; i < listTuitionFeeInDb.Count;i++)
            {
                tmp.Add(listTuitionFeeInDb[i]);
                if(i%3 == 2)
                {
                    tmp2.Add(tmp.Average());
                    tmp = new List<double>();
                }
            }
            if(tmp.Count != 0)
                tmp2.Add(tmp.Average());

                // Học phí trung bình cho cả hệ thống bằng trung bình các giá trị trung bình của bin
            TrungBinhPoint = tmp2.Average();
                // Xác nhận các điểm
                // Hơi ít
            HoiItPoint = TrungBinhPoint * 0.25;
            // Ít
            ItPoint = TrungBinhPoint * 0.5;
            // Hơi Cao
            HoiCaoPoint = TrungBinhPoint * 1.25;
            // Cao
            CaoPoint = TrungBinhPoint * 1.5;


            // Lấy ra ranking trong DB
            // Sắp xếp ranking từ nhỏ đến lớn
            var ratetheschool = (fc.db.SystemRatings.OrderBy(s => s.SystemRate).Select(s => s.SystemRate)).ToList();
            var distinctlistrate = (fc.db.SystemRatings.OrderBy(s => s.SystemRate).Select(s => s.SystemRate)).Distinct().ToList();
            
            // Xác định và loại outliners cho rankin
            var listrateinDb = outlier.Detection(ratetheschool, distinctlistrate);
            listrateinDb = outlier.Detection(listrateinDb);
            var tmprate = new List<double>();
            var tmprate2 = new List<double>();
            for (int i = 0; i < listrateinDb.Count; i++)
            {
                tmprate.Add(listrateinDb[i]);
                if (i % 3 == 2)
                {
                    tmprate2.Add(tmprate.Average());
                    tmprate = new List<double>();
                }
            }
            if (tmprate.Count != 0)
                tmprate2.Add(tmprate.Average());

            RateBinhThuong = tmprate2.Average();

            RateCao = RateBinhThuong * 1.25;

            RateRatCao = RateBinhThuong * 1.5;
        }

        public double GotTheFee()
        {
            var fc = new FunctionController();
            //var db = new SFCEntities();
            var record = (from s in fc.db.Schools orderby s.TuitionFee select s.TuitionFee).ToList();
            var temp = new List<double>();
            var thetemp = new List<double>();
            for (int i = 0; i < record.Count; i++)
            {
                double check = Math.Abs(feeMax - record[i]);
                if (check < 1000)
                {
                    temp.Add(check);
                    thetemp.Add(record[i]);
                }
            }

            return thetemp.ElementAt(temp.IndexOf(temp.Min()));
        }
    }
}
